package com.durian.base.permission;

import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;

import com.durian.BaseApp;
import com.durian.base.permission.listener.OnPermissionListener;
import com.durian.base.permission.task.IPermissionDialogDeploy;
import com.durian.base.permission.task.IPermissionTask;
import com.durian.base.permission.task.PermissionAudio;
import com.durian.base.permission.task.PermissionCamera;
import com.durian.base.permission.task.PermissionContacts;
import com.durian.base.permission.task.PermissionInstall;
import com.durian.base.permission.task.PermissionLocation;
import com.durian.base.permission.task.PermissionNotification;
import com.durian.base.permission.task.PermissionStorage;
import com.durian.base.permission.xx.OnPermission;
import com.durian.base.permission.xx.XXPermissions;
import com.durian.base.utils.ToolUtils;
import com.durian.ui.dialog.DialogAlert;
import java.io.File;
import java.util.ArrayList;
import java.util.List;


/**
 * 说明：SoonPermission
 * <p/>
 * 作者：fanly
 * <p/>
 * 类型：Class
 * <p/>
 * 时间：2019/4/23 16:23
 * <p/>
 * 版本：version 1.0
 */
public class SoonPermission implements RequestExecutor {

    private final String             TAG_SOON_PERMISSION_FRAGMENT = "TAG_SOON_PERMISSION_FRAGMENT";
    private       PermissionFragment mSoonPermissionFragment;
    private       FragmentActivity   mActivity;
    private ArrayList<IPermissionTask> mPermissionTaskList;
    public int                         currentTaskIndex = -1;
    private OnPermissionListener onPermissionCallback;
    private File installFile = null;

    private SoonPermission(FragmentActivity activity,FragmentManager manager) {
        if (ToolUtils.isNotFinish(activity)) {
            findSoonPermissionFragment(activity, manager);
        }
        mActivity = activity;
        mPermissionTaskList = new ArrayList<>();
    }

    public static SoonPermission with(FragmentActivity activity) {
        return new SoonPermission(activity,activity.getSupportFragmentManager());
    }

    public static SoonPermission with(Fragment fragment) {
        return new SoonPermission(fragment.getActivity(),fragment.getChildFragmentManager());
    }

    private void findSoonPermissionFragment(FragmentActivity activity, FragmentManager manager) {
        if (activity != null && manager != null) {
            Fragment fragment = manager.findFragmentByTag(TAG_SOON_PERMISSION_FRAGMENT);
            if (fragment == null) {
                mSoonPermissionFragment = new PermissionFragment();
                manager.beginTransaction().add(mSoonPermissionFragment, TAG_SOON_PERMISSION_FRAGMENT).commitAllowingStateLoss();
                manager.executePendingTransactions();
            } else if (fragment instanceof PermissionFragment) {
                mSoonPermissionFragment = (PermissionFragment) fragment;
            }
        }
    }

    public SoonPermission setPermissionListener(OnPermissionListener listener) {
        onPermissionCallback = listener;
        if (mSoonPermissionFragment != null) {
            mSoonPermissionFragment.setCallback(listener);
        }
        return this;
    }

    private boolean hasPermissionTask(IPermissionTask permissionTask) {
        boolean has = false;
        for (IPermissionTask task : mPermissionTaskList) {
            if (task.equals(permissionTask)) {
                has = true;
                break;
            }
        }
        return has;
    }

    public void addPermissionTask(IPermissionTask permissionTask) {
        if (!hasPermissionTask(permissionTask)) {
            mPermissionTaskList.add(permissionTask);
        }
    }

    /**
     * 定位权限
     *
     * @return
     */
    public SoonPermission location() {
        addPermissionTask(new PermissionLocation());
        return this;
    }

    /**
     * 存储权限
     *
     * @return
     */
    public SoonPermission storage() {
        addPermissionTask(new PermissionStorage());
        return this;
    }

    /**
     * 相机权限
     *
     * @return
     */
    public SoonPermission camera() {
        addPermissionTask(new PermissionCamera());
        return this;
    }

    /**
     * 联系人权限
     *
     * @return
     */
    public SoonPermission contacts() {
        addPermissionTask(new PermissionContacts());
        return this;
    }


    /**
     * 录音权限
     *
     * @return
     */
    public SoonPermission audio() {
        addPermissionTask(new PermissionAudio());
        return this;
    }

    /**
     * 通知权限
     * @return
     */
    public SoonPermission notification() {
        addPermissionTask(new PermissionNotification());
        return this;
    }

    /**
     * 安装权限
     * @return
     */
    public SoonPermission install(File file) {
        addPermissionTask(new PermissionInstall());
        installFile = file;
        return this;
    }

    public void start() {
        if (!ToolUtils.isNotFinish(mActivity)) {
            return;
        }
        if (mPermissionTaskList.isEmpty()) {
            return;
        }
        if (hasAllPermission()) {
            onGranted();
            return;
        }
        if (onPermissionCallback != null) {
            if (!onPermissionCallback.rationale(this)){
                execute();
            }
        } else {
            execute();
        }
    }

    private void onGranted(){
        if (onPermissionCallback != null) {
            onPermissionCallback.onGranted();
            if (installFile != null){
                toInstall();
            }
        }
    }

    private boolean hasAllPermission(){
        ArrayList<String> list = new ArrayList<>();
        for (IPermissionTask task:mPermissionTaskList){
            list.addAll(task.permissionGroup());
        }
        return XXPermissions.hasPermission(mActivity, list);
    }

    @Override
    public void execute() {
        int size = mPermissionTaskList.size();
        currentTaskIndex++;
        if (currentTaskIndex == size){
            onGranted();
            return;
        }
        IPermissionTask task = mPermissionTaskList.get(currentTaskIndex);
        mSoonPermissionFragment.setCallback(onPermissionCallback);
        mSoonPermissionFragment.setSoonPermission(this);
        XXPermissions.with(mActivity)
                .permission(task.permissionGroup())
                .request(new OnPermission() {
                    @Override
                    public void hasPermission(List<String> granted, boolean all) {
                        if (all) {
                            execute();
                        }
                    }
                    @Override
                    public void noPermission(List<String> denied, boolean never) {
                        if (never){
                            showNeverNoPermissionDialog(task);
                        }else {
                            onDenied(task);
                        }
                    }
                });
    }

    public void onDenied(IPermissionTask task) {
        if (onPermissionCallback != null){
            currentTaskIndex--;
            onPermissionCallback.onDenied(SoonPermission.this,task);
        }
    }

    private void onCancel(){
        if (onPermissionCallback != null){
            onPermissionCallback.onCancel();
        }
    }

    private void showNeverNoPermissionDialog(IPermissionTask task) {
        DialogAlert.create(mActivity)
                .setCancel(false)
                .setMessage(task.deniedMessage())
                .setCancelText(IPermissionDialogDeploy.CANCEL)
                .setCancelListener(new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        onCancel();
                    }
                })
                .setConfirmText(IPermissionDialogDeploy.TO_SETTING)
                .setConfirmListener(new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        mSoonPermissionFragment.setTask(task);
                        mSoonPermissionFragment.startPermissionActivity();
                    }
                })
                .show();
    }

    private void toInstall(){
        if (installFile != null) {
            Intent intent = new Intent("android.intent.action.INSTALL_PACKAGE");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri uri = ToolUtils.getFileUri(mActivity, installFile);
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
            BaseApp.getApp().startActivity(intent);
        }
    }
}
